import asyncio
import threading
import time
import json
import openpyxl
from io import BytesIO
from uuid import UUID
from loguru import logger
from pydantic import BaseModel
from datetime import datetime
from typing import Optional
from typing import List, Dict, Any
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.interval import IntervalTrigger

from bisheng.api.jsj_api.tool_service import MetroFaultService
from bisheng.api.jsj_api.message_service import MessageService
from bisheng.api.jsj_api.power_service import  PowerService
from bisheng.api.jsj_api.config_service import ConfigService
from fastapi import (APIRouter, Form, UploadFile, File, Query, Path, HTTPException,
                     BackgroundTasks, WebSocket, WebSocketDisconnect,Body)
from bisheng.api.jsj_api.tool_model import UpdateMetroFault, LevelReq, ConfigReq
from bisheng.api.jsj_api.task_service import TaskService
from bisheng.api.jsj_api.uat_tool_service import UatService
from bisheng.api.jsj_api.equipment_service import EquipmentService, MaintenanceRuleService
from bisheng.scheduler import get_scheduler
from bisheng.websocket import ws_manager
from bisheng.utils.logger import logger

# build router
router = APIRouter(prefix='/tool', tags=['OpenAPI', 'tool'])

global_group_id = 'ad586012-c11c-11ef-948d-38f3ab90c3e7'


class MetroFaultCreate(BaseModel):
    report_order_code: str
    line: str = ''
    equipment_id: str = ''
    fault_phenomenon: Optional[str] = None
    occurrence_time: Optional[datetime] = None
    fix_time: Optional[datetime] = None
    impact_operation: Optional[int] = 0
    impact_operation_time: Optional[str] = ''
    impact_service_time: Optional[str] = ''
    safety_impact_level: Optional[str] = '不影响'
    env_impact_level: Optional[str] = '不影响'
    incidence: Optional[str] = '部件本体/设备本体'
    equipment_name: Optional[str] = ''
    report_file_url: Optional[str] = ''


class MessageDetail(BaseModel):
    alarm_time: Optional[str] = ''  # 使用字符串类型接收原始数据
    alarm_level: Optional[str] = ''
    station: Optional[str] = ''
    equipment: Optional[str] = ''
    description: Optional[str] = ''
    status: Optional[str] = ''


class AddMessage(BaseModel):
    group_id: Optional[str] = ''
    # message_type: str = ''
    alarm_time: Optional[datetime] = None
    alarm_level: Optional[str] = None
    station: Optional[str] = ''
    equipment: Optional[str] = ''
    # switch: Optional[str] = ''
    # point: Optional[str] = ''
    description: Optional[str] = ''
    location: Optional[str] = ''
    # status: Optional[str] = ''
    # switch_order: Optional[str] = None
    IO_AI_detail: Optional[str] = None
    type: Optional[str] = ''

    message_list: List[MessageDetail] = []  # 允许空列表
    message_list_url:  Optional[str] = ''

class AddEquipment(BaseModel):
    loop_diagrams: Optional[str] = ''
    fault: Optional[str] = ''
    equipment: Optional[str] = ''
    equipment_type: Optional[str] = ''

class UpdateAlarmStatus(BaseModel):
    chat_id: Optional[str] = ''
    status: Optional[str] = ''
    update_time: Optional[str] = ''

class MetroKV(BaseModel):
    key: Optional[str] = ''
    value: Optional[str] = ''
    type: Optional[str] = ''


@router.post("/metro_faults/json/create", status_code=200)
def create_metro_fault(
    background_tasks: BackgroundTasks,
    fault_data: MetroFaultCreate
):
    service = MetroFaultService()

    if fault_data.equipment_id == '':
        raise Exception("Equipment id can't be empty")

    file = None
    if fault_data.report_file_url:
        file = service.download_file(fault_data.report_file_url)

    new_fault = service.create_metro_fault(fault_data.dict(), file, background_tasks)

    return {"message": "创建故障成功", "report_order_code": str(new_fault.report_order_code), "status": 200}


@router.post("/metro_faults/form/create", status_code=200)
def create_metro_fault(
        background_tasks: BackgroundTasks,
        report_order_code: str = Form(...),
        line: str = Form(default=''),
        equipment_id: str = Form(default=''),
        fault_phenomenon: Optional[str] = Form(None),
        occurrence_time: Optional[datetime] = Form(None),
        fix_time: Optional[datetime] = Form(None),
        impact_operation: Optional[int] = Form(default=0),
        impact_operation_time: Optional[str] = Form(default=''),
        impact_service_time: Optional[str] = Form(default=''),
        safety_impact_level: Optional[str] = Form(default='不影响'),
        env_impact_level: Optional[str] = Form(default='不影响'),
        incidence: Optional[str] = Form(default='部件本体/设备本体'),
        equipment_name: Optional[str] = Form(default=''),
        report_file_url: Optional[str] = Form(default=''),
        report_file: Optional[UploadFile] = File(default=None),
):
    service = MetroFaultService()

    fault_data = {
        "report_order_code": report_order_code,
        "line": line,
        "equipment_id": equipment_id,
        "fault_phenomenon": fault_phenomenon,
        "occurrence_time": occurrence_time,
        "fix_time": fix_time,
        "impact_operation": impact_operation,
        "impact_operation_time": impact_operation_time,
        "impact_service_time": impact_service_time,
        "safety_impact_level": safety_impact_level,
        "env_impact_level": env_impact_level,
        "incidence": incidence,
        "equipment_name": equipment_name
    }
    if equipment_id == '':
        raise Exception("Equipment id can't be empty")
    if report_file_url:
        file = service.download_file(report_file_url)
    else:
        file = report_file
    new_fault = service.create_metro_fault(fault_data, file, background_tasks)

    return {"message": "创建故障成功", "report_order_code": str(new_fault.report_order_code), "status": 200}


@router.get("/metro_faults/{equipment_id}", status_code=200)
def get_metro_faults_by_equipment_id(equipment_id: str):
    service = MetroFaultService()
    metro_faults = service.get_metro_faults_by_equipment_id(equipment_id)
    return metro_faults


@router.post("/metro_faults/update", status_code=200)
def update_metro_fault(metro_fault: UpdateMetroFault):
    """更新地铁故障记录"""
    service = MetroFaultService()
    updated_fault = service.update_metro_fault(metro_fault)
    return updated_fault


@router.post("/metro_faults/level", status_code=200)
def get_level_by_equipment_id(req: LevelReq):
    """大模型获取影响等级的function_call"""
    service = MetroFaultService()
    level = service.get_importance_level(req.equipment_id)
    reports, equipment_name = service.get_report_by_equipment_id(req.equipment_id)
    ##默认 有设备信息
    return {"equipment_msg": equipment_name, "level": level, "reports": reports}


@router.get("/metro_faults_level")
def get_level_by_equipment_id(equipment_id: str = Query(description="设备的唯一标识符")):
    """根据设备id获取等级影响"""
    service = MetroFaultService()
    level = service.get_importance_level(equipment_id)
    reports_str, equipment_name = service.get_report_by_equipment_id(equipment_id)
    return {"equipment_msg": equipment_name, "level": level, "reports": reports_str}


@router.get("/metro_faults_suggestion")
def get_suggestion_by_equipment_id(equipment_id: str = Query(description="设备的唯一标识符")) -> Dict[str, Any]:
    """根据设备id获取建议"""
    service = MetroFaultService()
    level = service.get_importance_level(equipment_id)
    task_list = TaskService().get_tasks_by_equipment_id(equipment_id)
    if task_list is None or len(task_list) == 0:
        return {"content": [{"suggestion": "暂无建议"}], "level": level, "equipment_id": equipment_id}
    return_content_list = []
    for task in task_list:
        suggestion_dict = {"strategy_name": task.strategy_name,
                           "strategy_number": task.strategy_number}
        content = service.get_suggestion(task, 1, 1)
        if content is None or content == "":
            suggestion_dict["suggestion"] = task.suggestion
            if task.suggestion is None or task.suggestion == "":
                suggestion_dict["suggestion"] = "暂无建议"
        else:
            suggestion_dict["suggestion"] = content
        return_content_list.append(suggestion_dict)

    return {"content": return_content_list, "level": level, "equipment_id": equipment_id}


@router.get("/metro_config")
def get_config():
    # 获取配置
    service = ConfigService()
    return service.get_config()


@router.post("/metro_config/create")
def create_config(create_req: ConfigReq):
    # 创建数据库配置
    service = ConfigService()
    return service.create_config(create_req.key, create_req.value, create_req.remark)


@router.post("/metro_config/update")
def update_config(update_req: ConfigReq):
    # 更新数据库配置
    service = ConfigService()
    return service.update_config(update_req.key, update_req.value, update_req.remark)


@router.post("/sync_equipment_info")
async def sync_equipment_info():
    # 获取所有设备信息
    service = EquipmentService()
    service.delete_all()
    await service.sync_equipments(20, 1)


@router.post("/sync_maintenance_rule_info")
async def sync_maintenance_rule_info():
    # 获取所有设备信息
    service = MaintenanceRuleService()
    service.delete_all()
    await service.sync_maintenance_rule(20, 1)


@router.post("/add_message")
async def add_message(messages: List[AddMessage]):
    for message in messages:
        message.type = "message"
        print(message.json())
        tool_service = MetroFaultService()
        tool_service.create_message(message.dict())
        ws_manager.broadcast(json.dumps(message.dict(),cls=UUIDEncoder))
        print("完成")
    return {"message": "添加成功", "code": 200}

@router.post("/add_alarm")
async def add_alarm(alarm: AddMessage):
    need_broadcast = True
    tool_service = MetroFaultService()
    logger.info("----------------开始-------------------")
    logger.info(alarm)
    if "DDL" not in alarm.description and "ddl" not in alarm.description and "311" not in alarm.description:
        logger.info("----------------不包含DDL or 311-------------------")
        return {"message": "添加成功", "code": 200}
    if alarm.group_id is not None and alarm.group_id != "":
        # message_list_dicts = [message.dict() for message in alarm.message_list]
        # download_url = tool_service.upload_message_to_oss(alarm.group_id, message_list_dicts)
        download_url = ""
        alarm.message_list_url = download_url
        alarm.type = "sync_alarm"
        alarm_record_list = tool_service.get_alarm_record_by_group_id("cba2ef5a84ec4785b244edf551cb83c6")
        if alarm_record_list is not None:
            alarm_record = alarm_record_list[0]
            alarm.description = alarm_record.description
            alarm.alarm_level = alarm_record.alarm_level
            alarm.equipment = alarm_record.equipment
            alarm.station = alarm_record.station
        # groups = tool_service.get_alarm_record_by_group_id(alarm.group_id)
        # if groups is not None and len(groups) > 0:
        #     need_broadcast = False
    alarm_record = tool_service.add_alarm_record(alarm.dict())
    alarm_record_dict = alarm_record.dict()
    alarm_record_dict["alarm_time"] = str(alarm_record.alarm_time)
    # alarm_record_dict["type"] = "alarm"
    logger.info("----------------完成-------------------")
    if need_broadcast:
        ws_manager.broadcast(json.dumps(alarm_record_dict,cls=UUIDEncoder))
    return {"message": "添加成功", "code": 200, "group_id": alarm_record_dict.get("group_id")}




@router.post("/add_alarm_message")
async def add_alarm_message(message: AddMessage):
    need_broadcast = True
    tool_service = MetroFaultService()
    if message.group_id is not None and message.group_id != "":
        groups = tool_service.get_alarm_record_by_group_id(message.group_id)
        if groups is not None and len(groups) > 0:
            need_broadcast = False
    alarm_record = tool_service.add_alarm_record(message.dict())
    alarm_record_dict = alarm_record.dict()
    alarm_record_dict["alarm_time"] = str(alarm_record.alarm_time)
    alarm_record_dict["type"] = "alarm"
    # if need_broadcast:
    #     await ws_manager.broadcast(json.dumps(alarm_record_dict,cls=UUIDEncoder))
    return {"message": "添加成功", "code": 200, "group_id": alarm_record_dict.get("group_id")}


@router.get("/alarm_message_list")
def get_alarm_message_list(num: Optional[str] = Query(default=None, description="第几个故障")):
    tool_service = MetroFaultService()
    if num == "" or num is None or num == "0":
        return tool_service.get_alarm_record_list_by_num(None)
    else:
        return tool_service.get_alarm_record_list_by_num(int(num))

@router.get("/alarm_message_group")
def get_alarm_message_group(num: str = Query(description="第几个故障")):
    tool_service = MetroFaultService()
    if num == "" or num is None or num == "0":
        records = tool_service.get_alarm_record_group_by_num(None)
    else:
        records = tool_service.get_alarm_record_group_by_num(int(num))

    if records is None or len(records) == 0:
        return "未查询到这个故障"
    return records


# @router.post("/create_fault_work_order")
@router.api_route("/create_fault_work_order", methods=["POST", "GET"])
async def create_fault_work_order(group_id: Optional[str] = Query(default=None, description="告警id"),chat_id: Optional[str] = Query(default=None, description="chat_id")):
    if group_id is None or group_id == "":
        group_id = global_group_id
    chat_id = chat_id.split("_")[0]
    tool_service = MetroFaultService()
    fwo,need_send_message_flag = tool_service.create_fault_work_order(group_id,chat_id)
    print(fwo,need_send_message_flag)

    if need_send_message_flag:
        message_service = MessageService()
        # message_service.send_bc_message(group_id,chat_id)
        # 在后台线程中运行消息发送任务
        run_in_thread(message_service.send_bc_message, group_id,chat_id)
        # run_in_thread(message_service.send_message_c_first, global_group_id)
    return f"<a href='/ev/work-order?id={fwo['id']}&type=order' target='_blank' class='blank-link'>查看工单:{fwo['code']}</a>"
    # return f"<iframe>id={fwo['id']}&type=order</iframe>"


#@router.post("/create_fault_work_ticket")
@router.api_route("/create_fault_work_ticket", methods=["POST", "GET"])
def create_fault_work_ticket(group_id: Optional[str] = Query(default=None, description="告警id"),chat_id: Optional[str] = Query(default=None, description="chat_id")):
    if group_id is None or group_id == "":
        group_id = global_group_id
    chat_id = chat_id.split("_")[0]
    tool_service = MetroFaultService()
    fwt = tool_service.create_fault_work_ticket(group_id,chat_id)
    return f"<a href='/ev/work-ticket?id={fwt['id']}&type=ticket' target='_blank' class='blank-link'>查看工作票:{fwt['code']}</a>"
    # return f"<iframe>id={fwt['id']}&type=ticket</iframe>"


#@router.post("/create_fault_work_plan")
@router.api_route("/create_fault_work_plan", methods=["POST", "GET"])
def create_fault_work_plan(group_id: Optional[str] = Query(default=None, description="告警id")):
    if group_id is None or group_id == "":
        group_id = global_group_id
    tool_service = MetroFaultService()
    fwp = tool_service.create_fault_work_plan(group_id)
    return f"<a href='/ev/work-plan?id={fwp['id']}&type=plan' target='_blank' class='blank-link'>查看施工计划:{fwp['code']}</a>"
    # return f"<iframe>id={fwp['id']}&type=plan</iframe>"

#@router.post("/create_fault_work_repair")
@router.api_route("/create_fault_work_repair", methods=["POST", "GET"])
def create_fault_work_repair(group_id: Optional[str] = Query(default=None, description="告警id")):
    if group_id is None or group_id == "":
        group_id = global_group_id
    tool_service = MetroFaultService()
    fwr = tool_service.create_fault_work_repair(group_id)
    return f"<a href='/ev/work-repair?id={fwr['id']}&type=repair' target='_blank' class='blank-link'>查看维修计划:{fwr['code']}</a>"
    # return f"<iframe>id={fwp['id']}&type=plan</iframe>"


@router.get("/loop_diagrams_equipment")
def loop_diagrams_equipment(equipment: Optional[str] = Query(default=None, description="设备名称"),fault: Optional[str] = Query(default=None, description="故障名称")):
    tool_service = MetroFaultService()
    if equipment is None or equipment == "":
        equipment = None
    if fault is None or fault == "":
        fault = None
    if equipment is None and fault is None:
        return tool_service.get_all_loop_diagrams()

    equipment_infos = tool_service.get_loop_diagrams_equipment(equipment,fault)
    str_result = ""
    if equipment_infos is None or len(equipment_infos) == 0:
        return str_result
    for equipment_info in equipment_infos:
        if equipment_info.loop_diagrams is not None and equipment_info.loop_diagrams != "":
            str_result += f"<img src='{equipment_info.loop_diagrams}'/>"

    return str_result


@router.get("/get_all_loop_diagrams")
def get_all_loop_diagrams():
    tool_service = MetroFaultService()
    return tool_service.get_all_loop_diagrams()

@router.get("/get_all_video")
def get_all_video():
    tool_service = MetroFaultService()
    return tool_service.get_all_video()


@router.post("/add_equipment_info")
def add_equipment_info(equipment:AddEquipment):
    tool_service = MetroFaultService()
    return tool_service.add_equipment_info(equipment.dict())

@router.get("/get_order_or_ticket")
def get_equipment_info(id: str = Query(description="工单id or工作票id"), type: str = Query(description="order or ticket")):
    tool_service = MetroFaultService()
    return tool_service.get_order_or_ticket(id, type)


@router.get("/create_order_docx")
def get_doc_url(group_id: str = Query(description="故障组id")):
    tool_service = MetroFaultService()
    path = tool_service.create_fault_docx(group_id, "order")
    return f"<iframe>{path}</iframe>"


@router.get("/create_ticket_docx")
def get_doc_url(group_id: str = Query(description="故障组id")):
    tool_service = MetroFaultService()
    path = tool_service.create_fault_docx(group_id, "ticket")
    return f"<iframe>{path}</iframe>"

@router.get("/get_suggest_questions")
def get_suggest_questions(chat_id:str = Query(description="会话id")):
    power_service = PowerService()
    questions = power_service.get_suggest_question(chat_id)
    return questions

@router.get("/get_suggest_questions_by_workflow")
def get_suggest_questions(chat_id:str = Query(description="会话id")):
    power_service = PowerService()
    questions = power_service.get_suggest_question(chat_id,workflow=True)
    return questions

@router.post("/update_alarm_status")
def update_alarm_status(alarm_status_info:UpdateAlarmStatus):
    tool_service = MetroFaultService()
    return tool_service.update_alarm_status(alarm_status_info.chat_id,alarm_status_info.status,alarm_status_info.update_time)

@router.get("/get_alarm_status_list")
def get_alarm_status_list(chat_id:str = Query(description="会话id")):
    tool_service = MetroFaultService()
    return tool_service.get_alarm_status_by_chat_id(chat_id)

@router.get("/get_question_str_first")
def get_question_str_first():
    tool_service = MetroFaultService()
    return tool_service.get_question_str_first(global_group_id,global_group_id)
    # group_id = tool_service.get_last_group_id()
    # return tool_service.get_order_ticket_plan_request(global_group_id,"您好，变电班长王青铁通知您对于","针对故障","")

@router.get("/get_question_str_secend")
def get_question_str_secend():
    tool_service = MetroFaultService()
    return tool_service.get_question_str_secend(global_group_id,global_group_id)
    # group_id = tool_service.get_last_group_id()
    # return tool_service.get_order_ticket_plan_request(global_group_id,"您好，李青海施工负责人，还有1小时您的","","需要召开预想会:会议内容如下:\n (1)本次工作简述 \n (2)工具清单 \n (3)安全宣贯")


@router.get("/get_question_str_third")
def get_question_str_third():
    tool_service = MetroFaultService()
    return tool_service.get_question_str_third(global_group_id,global_group_id)
    # group_id = tool_service.get_last_group_id()
    # now = datetime.now()
    # formatted_date = now.strftime("%Y-%m-%d %H:%M:%S")
    # formatted_day = now.strftime("%Y-%m-%d")
    # return tool_service.get_order_ticket_plan_request(global_group_id,f"您好，张青铁工程师，您在{formatted_day}下发的故障工单，",f"已有王青铁维修人员完成故障处置，完成时间:{formatted_date}，详细信息是","")

# @router.get("/get_word_url")
# def get_word_url(content: str = Query(description="markdown内容")):
#     tool_service = MetroFaultService()
#     return tool_service.get_word_url(content)


@router.post("/send_xlsx_message")
async def send_xlsx_message(file: UploadFile = File(...)):

    # 读取上传的文件内容
    contents = await file.read()
    workbook = openpyxl.load_workbook(filename=BytesIO(contents))
    sheet = workbook.active

    tool_service = MetroFaultService()
    # 从第二行开始遍历（跳过第一行）
    for row in sheet.iter_rows(min_row=2, max_col=7, values_only=True):
        row_data = [str(cell) if cell is not None else "" for cell in row]
        print("-------------------")
        print(row_data)
        message = AddMessage(
            alarm_time=convert_to_mysql_format(row_data[2]),
            message_type=row_data[1],
            alarm_level=row_data[3],
            station=row_data[4],
            equipment='1500V直流7#馈线柜',
            switch='211',
            point=row_data[4],
            description=row_data[5],
            location='1500V直流7#馈线柜',
            status=row_data[6],
            switch_order=None,
            IO_AI_detail=None,
            type='message',
        )

        tool_service.create_message(message.dict())
    return 200


@router.get("/get_agent_id_by_username")
def get_agent_id_by_username(username: str = Query(description="username")):
    tool_service = MetroFaultService()
    return tool_service.get_agent_id_by_username(username)

@router.get("/get_alarm_report_by_group_id")
def get_alarm_report_by_group_id(group_id: str = Query(description="故障组id"),chat_id: str = Query(description="会话ID")):
    power_service = PowerService()
    return  power_service.get_alarm_report_by_group_id(group_id,chat_id)

@router.get("/chat/history")
def get_chat_history(
                    chat_id: str = Query(description="会话id"),
                    # flow_id: str = Query(description="工作流id"),
                    page_size: Optional[int] = 100):
    power_service = PowerService()
    if not chat_id :
        return {'code': 500, 'message': 'chat_id 必传参数'}
    return power_service.get_chat_history(chat_id,page_size=page_size)

@router.get("/get_time_by_group_id")
def get_time_by_group_id(group_id: str = Query(description="故障组id"),
                         time_interval_min: Optional[int] = 180):
    tool_service = MetroFaultService()
    return tool_service.get_time_by_group_id(group_id,time_interval_min)


@router.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    logger.info(f"ws-websocket:{websocket}")
    try:
        await ws_manager.connect(websocket)
        logger.info(f"connect --------")
        await continuous_execution(websocket)
        while True:

            data = await websocket.receive_text()
            # 处理接收到的数据
            ws_manager.send_personal_message(f"{data}", websocket)
            # await manager.broadcast(f"Client says: {data}")
    except WebSocketDisconnect:
        ws_manager.disconnect(websocket)
    finally:
        # 确保在任何情况下都断开连接
        ws_manager.disconnect(websocket)


def run_in_thread(func, *args):
    thread = threading.Thread(target=func, args=args)
    thread.start()


async def continuous_execution(websocket: WebSocket):
    try:

        await send_message_and_alarm(websocket)
        # while True:
        #     # 执行您的方法
        #     result = await send_message_and_alarm(websocket)
        #
        #     # 将结果发送给客户端
        #     await manager.send_personal_message(result, websocket)
        #
        #     # 等待一段时间再次执行（例如5秒）
        #     await asyncio.sleep(5)
    except WebSocketDisconnect:
        # 当 WebSocket 断开连接时，这个循环会结束
        ws_manager.disconnect(websocket)
        print("WebSocket disconnected")


async def send_message_and_alarm(websocket: WebSocket):
    tool_service = MetroFaultService()
    alarm_records = tool_service.get_alarm_record_by_type("alarm")
    sync_alarm_records = tool_service.get_alarm_record_by_type("sync_alarm",1)
    list = []
    for alarm_record in alarm_records:
        # now = datetime.now()
        # alarm_record.alarm_time = now
        # alarm_record.alarm_time = "2025-03-05 09:05:38"
        # alarm_record.alarm_time = now.strftime("%Y-%m-%d %H:%M:%S")
        try:
            if alarm_record.alarm_number == 0:
                # continue
                await websocket.send_text(json.dumps(alarm_record.dict(), cls=UUIDEncoder))
            else :
                if alarm_record.alarm_number in list:
                    await websocket.send_text(json.dumps(alarm_record.dict(), cls=UUIDEncoder))
                    # continue
                else:
                    await websocket.send_text(json.dumps(alarm_record.dict(), cls=UUIDEncoder))
                    list.append(alarm_record.alarm_number)

        except Exception as e:
            print("WebSocket connection closed normally", e)
            raise  # 结束函数
        await asyncio.sleep(1)
    #最后发送同步过来的告警
    for sync_alarm in sync_alarm_records:
        try:
           await websocket.send_text(json.dumps(sync_alarm.dict(), cls=UUIDEncoder))
        except Exception as e:
            print("WebSocket connection closed normally", e)
            raise  # 结束函数
        await asyncio.sleep(1)


# --------------新版本工具-----------------

@router.get("/get_message_url_by_group_id")
def get_message_url_by_group_id(group_id: str = Query(description="group_id")):
    tool_service = MetroFaultService()
    alarm_records = tool_service.get_alarm_record_by_group_id(group_id)
    if alarm_records is None or len(alarm_records) == 0:
        return ""
    return alarm_records[0].message_list_url

@router.get("/get_waveform_by_group_id")
def get_waveform_by_group_id(group_id: str = Query(description="group_id")):
    tool_service = MetroFaultService()
    alarm_records = tool_service.get_alarm_record_by_group_id(group_id)
    if alarm_records is None or len(alarm_records) == 0:
        return ""
    if alarm_records[0].waveform_url is None:
        return "http://120.221.212.173:30092/jsj-bucket/lubo.png"
    return alarm_records[0].waveform_url
    # if "故障A" in alarm_records[0].description:
    #     return "http://120.221.212.173:30092/jsj-bucket/luboA.png"
    # if "故障B" in alarm_records[0].description:
    #     return "http://120.221.212.173:30092/jsj-bucket/luboB.png"

@router.get("/get_equipment_principle_by_group_id")
def get_equipment_principle_by_group_id(group_id: str = Query(description="group_id")):
    if group_id is None:
        return ""
    tool_service = MetroFaultService()
    alarm_records = tool_service.get_alarm_record_by_group_id(group_id)
    if alarm_records is None or len(alarm_records) == 0:
        return ""
    return alarm_records[0].equipment_principle_url


@router.get("/get_logic_relation_by_group_id")
def get_logic_relation_by_group_id(group_id: str = Query(description="group_id")):
    if group_id is None:
        return ""
    tool_service = MetroFaultService()
    alarm_records = tool_service.get_alarm_record_by_group_id(group_id)
    if alarm_records is None or len(alarm_records) == 0:
        return ""
    return alarm_records[0].logic_relation_url



@router.get("/get_schedule_record_by_date")
def get_schedule_record_by_date(date: str = Query(description="date")):
    return {"message":"李德志,电话13560792616"}


# 创建工作票
#入参
@router.get("/create_fault_work_ticket_new")
def create_fault_work_ticket_new(group_id: str = Query(description="group_id")):
    if not group_id:
        return {"error": "group_id 不能为空"}# 如果group_id 为空返回错误信息
    # uat_service = UatService()
    # uat_service.create_fault_work_ticket_new(group_id)
    return {"ticket_num": "T1234-5678-0000"}

# 创建施工计划
# 入参
@router.get("/create_fault_work_repair_new")
def create_fault_work_repair_new(group_id: str = Query(description="group_id")):
    """
    创建一个新的故障工单维修记录。
    Args:
        request_body (dict):  请求体, 必须包含 group_id。  例如: {"group_id": "your_group_id"}
    Returns:
        dict:  包含 repair_num 的字典。
    """

    if not group_id:
        return {"error": "group_id 不能为空"} #如果group_id 为空返回错误信息
    # uat_service = UatService()
    # plan_num = uat_service.create_fault_work_repair_new(group_id)
    # 返回 repair_num
    return {"repair_num": "6B2-26-01"}


@router.get("/create_docx_by_str")
def create_docx_by_str(content: str = Query(description="content")):
    if not content:
        return {"error": "content 不能为空"}
    print(content)
    uat_service = UatService()
    download_url = uat_service.create_word_with_images(content)
    print(download_url)
    if download_url is None:
        return {"doc_url": "http://120.221.212.173:30092/jsj-bucket/lubo.png"}
    return {"doc_url": download_url.replace('http://172.16.100.149:9100','http://120.221.212.173:30092')}

@router.get("/get_alarm_by_group_id")
def get_alarm_by_group_id(group_id: str = Query(description="group_id")):
    if not group_id:
        return {"error": "group_id 不能为空"}
    tool_service = MetroFaultService()
    alarm_records = tool_service.get_alarm_record_by_group_id(group_id)
    if alarm_records is None or len(alarm_records) == 0:
        return {}
    return alarm_records[0]


@router.get("/get_alarm_stage_by_group_id")
def get_alarm_stage_by_group_id(group_id: str = Query(description="group_id")):
    if not group_id:
        return {"error": "group_id 不能为空"}
    tool_service = MetroFaultService()
    alarm_records = tool_service.get_alarm_record_by_group_id(group_id)
    if alarm_records is None or len(alarm_records) == 0:
        return {}
    return alarm_records[0].stage

@router.get("/save_alarm_stage")
def get_alarm_stage_by_group_id(group_id: str = Query(description="group_id"),stage:str = Query(description="stage")):
    if not group_id:
        return {"error": "group_id 不能为空"}
    uat_service = UatService()
    uat_service.save_alarm_stage(group_id, stage)
    return "success"


@router.get("/save_alarm_end_time")
def save_alarm_over_time(group_id: str = Query(description="group_id"),alarm_end_time: str = Query(description="alarm_end_time")):
    if not group_id:
        return {"error": "group_id 不能为空"}
    uat_service = UatService()
    uat_service.save_alarm_end_time(group_id, alarm_end_time)
    return alarm_end_time

@router.post("/create_fault_work_order_new")
async def create_fault_work_order_new(group_id: str = Query(description="group_id"),a_chat_id: str = Query(description="a_chat_id")):
    if not group_id:
        return {"error": "group_id 不能为空"}
    uat_service = UatService()
    fwo = uat_service.create_fault_work_order_new(group_id,a_chat_id)

    message_service = MessageService()
    # message_service.send_bc_message(group_id,a_chat_id)
    # 在后台线程中运行消息发送任务
    # todo
    run_in_thread(message_service.send_bc_message, group_id,a_chat_id)
    # run_in_thread(message_service.send_message_c_first, global_group_id)
    return f"<a href='/ev/work-order?id={fwo['id']}&type=order' target='_blank' class='blank-link'>查看工单:{fwo['code']}</a>"
    # return f"<iframe>id={fwo['id']}&type=order</iframe>"

@router.get("/get_message_list_by_redis")
def get_message_list_by_redis():
    message_service = MessageService()
    return message_service.get_message_list_by_redis()

@router.get("/get_chat_message_by_chat_id")
def get_chat_message_by_chat_id(chat_id: str = Query(description="chat_id")):
    power_service = PowerService()
    return power_service.get_chat_message_by_chat_id(chat_id)

@router.post("/create_kv")
def create_kv(kv: MetroKV):
    config_service = ConfigService()
    return config_service.create_kv(kv.key, kv.value, kv.type)

@router.get("/get_kv_by_key")
def get_kv_by_key(
    key: Optional[str] = Query(None, description="搜索的键名（可空时会返回None）"),  # 非必填
    type: Optional[str] = Query(None, description="过滤的类型（非必填）")               # 非必填
):
    if not key:
        return None
    config_service = ConfigService()
    return config_service.get_kv_by_key(key, type)




class UUIDEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, UUID):
            return str(obj)
        elif isinstance(obj, datetime):
            return obj.strftime("%Y-%m-%d %H:%M:%S")  # 将datetime转换为指定格式的字符串
        return json.JSONEncoder.default(self, obj)

def convert_to_mysql_format(date_string):
    dt = datetime.strptime(date_string, "%Y年%m月%d日 %H:%M:%S:%f")
    return dt.strftime("%Y-%m-%d %H:%M:%S.%f")


# 定义定时任务
def scheduled_sync():
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    loop.run_until_complete(sync_equipment_info())
    loop.run_until_complete(sync_maintenance_rule_info())


scheduler = get_scheduler()
scheduler.add_job(scheduled_sync, IntervalTrigger(hours=24), id='sync_job')
